package com.googlecode.lohr.utils;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;

import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream;
import javax.crypto.spec.SecretKeySpec;

public class IOUtils
{
	private static String __Key= "x903,g8q";
    private static SecretKeySpec __sksSpec = new SecretKeySpec(__Key.getBytes(), "DES");
	public static final File REPOSITORY_HOME= new File(new File(new File(System.getProperty("user.home")), ".realtydata"), "docs");
	
    public static CipherOutputStream createEncryptedOutputStream(OutputStream outputStream) {
		try
		{
			Cipher cipher = Cipher.getInstance("DES");
			cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, __sksSpec);
			CipherOutputStream cipherOutputStream = new CipherOutputStream(outputStream, cipher);
			return cipherOutputStream;
		} 
		catch (Throwable e)
		{
			e.printStackTrace();
			throw new RuntimeException("Could not create encryped output stream:"+e.getMessage(), e);
		}		
    }

	/**
	 * Reads the entire file and returns a byte array of the contents.
	 */
	public static byte[] readFully(File file) 
	throws IOException
	{
		if (file.length() < Integer.MAX_VALUE) {
			// space optimized method for reading files...
			InputStream in= new BufferedInputStream(new FileInputStream(file));
			try
			{
				int length= (int)file.length();
				byte[] buffer= new byte[length];
				int offset= 0;
				int c;
				while (0 < length && (c= in.read(buffer, offset, length)) != -1) {
					offset+= c;
					length-= c;
				}
				return buffer;
			} 
			finally  {
				try { in.close(); } catch (Throwable t) { }
			}
		}

		return readFully(file.toURI().toURL());
	}
	
    /**
     * Delete directory and directory contents. Must be a directory path with no
     * file name.
     * @param directory directory to delete.
     * @return true directory was successfuly deleted.
     */
    public static final boolean deleteDirectory(File directory) {
        if (directory.isDirectory()) {
            String[] children = directory.list();
            for (int i=0; i<children.length; i++) {
                boolean success = deleteDirectory(new File(directory, children[i]));
                if (!success) 
                    return false;
            }
        }
        // Now use delete() since empty.
        return directory.delete();
    }

	public static void writeFully(byte[] imageData, File file) 
	throws IOException
	{
		FileOutputStream out= new FileOutputStream(file);
		try {
			out.write(imageData);
			out.flush();
		}
		finally {
			try { out.close(); } catch (Throwable t) { }
		}
	}

	  /**
	   * encrypt
	   */
	  public static byte[] encrypt(byte[] data) {
	    try
		{
			//Get Key From Out
			Cipher cipher = Cipher.getInstance("DES");
			cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, __sksSpec);
			byte[] encrypted = cipher.doFinal(data);
			return encrypted;
		} 
	    catch (Throwable e)
		{
			e.printStackTrace();
		}
	    return data;
	  }
	 
	  /**
	   * decrypt
	   */
	  public static byte[] decrypt(byte[] encrypted) {    
	    try
		{
			Cipher cipher = Cipher.getInstance("DES");
			cipher.init(javax.crypto.Cipher.DECRYPT_MODE, __sksSpec);
			byte[] decrypted = cipher.doFinal(encrypted);
			return decrypted;
		} 
	    catch (Throwable e)
		{
			e.printStackTrace();
		}
	    return encrypted;
	  }

	public static void close(OutputStream outputStream)
	{
		try {
			outputStream.close();			
		}
		catch (Throwable t) {			
		}
	}

	public static byte[] readFully(URL url) 
	throws IOException
	{
		InputStream in= new BufferedInputStream(url.openStream());
		try
		{
			return readFully(in);
		} 
		finally  {
			try { in.close(); } catch (Throwable t) { }
		}
	}

	public static byte[] readFully(InputStream in) 
	throws IOException
	{
		ByteArrayOutputStream out= new ByteArrayOutputStream();
		byte[] buffer= new byte[1024*64];
		int c;
		while ((c= in.read(buffer)) != -1)
			out.write(buffer, 0, c);
		return out.toByteArray();
	}



}
